import {
  Button,
  Form,
  FormItem,
  Image,
  Input,
  InputNumber,
  message,
  Modal,
  Space
} from 'ant-design-vue'
import { defineComponent, ref } from 'vue'

import { cinemaApi } from '@/apis'
import { BannerItem } from '@/apis/cinemaTypes'
import { type ProTableProps, type ProTableRef, ProTable } from '@/components'
import UploadFile from '@/components/UploadFile'
import { TABLE_FORMAT } from '@/constants'
import { useDialog } from '@/hooks'

export default defineComponent({
  name: 'MinAppBanner',
  setup() {
    const isAddStyle = ref(true)

    const curOptionItem = ref({} as BannerItem)
    const showDialog = ref(false)
    const dialogLoading = ref(false)
    const { showConfirm } = useDialog()

    const tableRef = ref({} as ProTableRef)
    const tableConfig = ref({
      fixedHeight: true,
      options: {
        border: true,
        align: 'center',
        formConfig: {
          items: [
            {
              slots: {
                default: 'addStyle'
              }
            }
          ]
        },
        columns: [
          {
            title: '轮播图名称',
            field: 'name',
            minWidth: 100
          },
          {
            title: '图片',
            field: 'img',
            width: 300,
            slots: {
              default: 'bannerImage'
            }
          },
          {
            title: '创建时间',
            field: 'createTime',
            minWidth: 200,
            formatter: [TABLE_FORMAT.Date, 'yyyy-MM-dd HH:mm:ss']
          },
          {
            title: '展示顺序',
            minWidth: 100,
            field: 'sort'
          },
          {
            title: '操作',
            fixed: 'right',
            slots: {
              default: 'operation'
            },
            width: 180
          }
        ],

        proxyConfig: {
          props: {
            result: 'data'
          },
          ajax: {
            query: async () => {
              const data = await cinemaApi.getBannerList()
              return data
            }
          }
        }
      }
    } as ProTableProps)

    //刷新
    async function refresh() {
      await tableRef.value.table.commitProxy('query')
    }

    // 编辑
    function handleEdit(item: BannerItem) {
      curOptionItem.value.id = item.id
      curOptionItem.value.name = item.name
      curOptionItem.value.img = item.img
      curOptionItem.value.sort = item.sort

      isAddStyle.value = false
      showDialog.value = true
    }

    //确定
    async function dialogConfirm() {
      if (!curOptionItem.value.name) {
        message.warn('请输入banner名称')
        return
      }
      if (!curOptionItem.value.img) {
        message.warn('请添加Banner图片')
        return
      }
      if (!curOptionItem.value.sort) {
        message.warn('请输入展示顺序')
        return
      }
      try {
        dialogLoading.value = true
        if (isAddStyle.value) {
          await cinemaApi.addBanner(curOptionItem.value)
        } else {
          await cinemaApi.editBanner(curOptionItem.value)
        }
        showDialog.value = false
        refresh()
      } finally {
        dialogLoading.value = false
      }
    }

    //新增
    function handleAdd() {
      curOptionItem.value.name = ''
      curOptionItem.value.img = ''
      curOptionItem.value.sort = 1

      isAddStyle.value = true
      showDialog.value = true
    }

    //删除
    function handleDelete(item: BannerItem) {
      showConfirm({
        content: `确定删除"${item.name}"？`,
        onOk: async () => {
          try {
            await cinemaApi.deleteBanner(item.id)
            refresh()
          } catch {}
        }
      })
    }

    return {
      tableRef,
      tableConfig,
      curOptionItem,
      showDialog,
      isAddStyle,
      dialogLoading,
      dialogConfirm,
      handleEdit,
      handleAdd,
      handleDelete
    }
  },
  render() {
    return (
      <div>
        <ProTable
          ref="tableRef"
          v-slots={{
            bannerImage: ({ row }) => <Image src={row.img}></Image>,
            addStyle: () => (
              <Button type="primary" onClick={this.handleAdd}>
                新增
              </Button>
            ),
            operation: ({ row }) => (
              <Space>
                <Button
                  type="link"
                  size="small"
                  onClick={() => this.handleEdit(row)}
                >
                  编辑
                </Button>
                <Button
                  type="link"
                  size="small"
                  onClick={() => this.handleDelete(row)}
                >
                  删除
                </Button>
              </Space>
            )
          }}
          {...this.tableConfig}
        />
        <Modal
          v-model:visible={this.showDialog}
          width={600}
          confirmLoading={this.dialogLoading}
          title={this.isAddStyle ? '新增' : '编辑'}
          destroyOnClose
          onOk={this.dialogConfirm}
        >
          <Form labelCol={{ span: 4 }} style={{ marginTop: '15px' }}>
            <FormItem label={'banner名称'} required>
              <Input
                placeholder={'请输入'}
                v-model:value={this.curOptionItem.name}
                style={{ width: '300px' }}
                maxlength={20}
                v-slots={{
                  suffix: () => <span>{this.curOptionItem.name.length}/20</span>
                }}
              />
            </FormItem>
            <FormItem label={'上传图片'} required>
              <UploadFile v-model={[this.curOptionItem.img, 'urls']}>
                上传图片
              </UploadFile>
            </FormItem>
            <FormItem label={'展示顺序'} required>
              <InputNumber
                placeholder={'请输入'}
                v-model:value={this.curOptionItem.sort}
                style={{ width: '300px' }}
                min={1}
                maxlength={4}
              />
              <p style={{ marginTop: '10px', color: '#888' }}>
                请输入大于等于1的整数，值越小排前面
              </p>
            </FormItem>
          </Form>
        </Modal>
      </div>
    )
  }
})
